/********************************** (C) COPYRIGHT *******************************
* File Name          : main.c
* Author             : WCH
* Version            : V1.0.0
* Date               : 2021/06/06
* Description        : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for 
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/

/*
 *@Note
 USART Print debugging routine:
 USART1_Tx(PA9).
 This example demonstrates using USART1(PA9) as a print debug port output.

*/

#include "debug.h"
#include "math.h"

/* Global typedef */
#define PI                 3.14159265358979f
/* Global define */

/* Global Variable */


/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */


void GPIO_config(void);
void TIM_config(void);
void DAC_config(void);
void bound_check(float *var);
uint8_t sec_idn(float angle);
void tim_cal(void);

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

float PWM_F= 5000; // <- chang for PWM_F
float T_svm;
float theta1=0,theta2=120,theta3=240,Va,Vb,Vc,Val,Vbe,spc_angle,spc_mag; //<-- angle and signal declaration
float MI=1.0f;
float clock=96000000;
float ARR_val;
uint8_t sig_flag=0,sector;
float T1,T2,T0,T1n,T2n,T0n;
float CMP1, CMP2, CMP3;

//uint16_t sw1
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n",SystemCoreClock);
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
    printf("This is printf example\r\n");

    T_svm= 0.0002;
    ARR_val =(clock/2)/PWM_F;
    GPIO_config();
    TIM_config();
    DAC_config();
    while(1)
    {
        if(sig_flag==1)
        {
            sig_flag=0;
            theta1++;
            bound_check(&theta1);
            theta2++;
            bound_check(&theta2);
            theta3++;
            bound_check(&theta3);
            Va =MI*sinf(theta1*PI/180)/2;
            Vb =MI*sinf(theta3*PI/180)/2;
            Vc =MI*sinf(theta2*PI/180)/2;

            Val =2*(Va-0.5f*(Vb+Vc))/3;
            Vbe = (Vb-Vc)/sqrt(3);
            spc_angle = atan2(Vbe,Val);
            if(spc_angle <0)
            {
                spc_angle = 2*PI + spc_angle;
            }
            spc_mag= sqrt(pow(Val,2)+pow(Vbe,2));
            sector = sec_idn(spc_angle*180/PI);
            tim_cal();

            switch(sector)
            {
                      case 1:
                                        CMP1 = T1 + T2 + T0/2;
                                        CMP2 = T2 + T0/2;
                                        CMP3 = T0/2;
                                        break;
                        case 2:
                                        CMP1 = T_svm - (T2 + T0/2);
                                        CMP2 = T1 + T2 + T0/2;
                                        CMP3 = T0/2;
                                        break;
                        case 3:
                                        CMP1 = T0/2;
                                        CMP2 = T1 + T2 + T0/2;
                                        CMP3 = T2 + T0/2;
                                        break;
                        case 4:
                                        CMP1 = T0/2;
                                        CMP3 = T1 + T2 + T0/2;
                                        CMP2 = T_svm-(T2 + T0/2);
                                        break;
                        case 5:
                                        CMP1 = T2 + T0/2;
                                        CMP2 = T0/2;
                                        CMP3 = T1 + T2 + T0/2;
                                        break;
                        case 6:
                                        CMP1 = T1 + T2 + T0/2;
                                        CMP2 = T0/2;
                                        CMP3 = T_svm-(T2 + T0/2);
                                        break;
                }

            DAC_SetChannel1Data(DAC_Align_12b_R,(CMP1*4095/T_svm));
            DAC_SetChannel2Data(DAC_Align_12b_R,(CMP2*4095/T_svm));

                CMP1 *= ARR_val/T_svm;
                CMP2 *= ARR_val/T_svm;
                CMP3 *= ARR_val/T_svm;

                TIM_SetCompare1(TIM1,CMP1);
                TIM_SetCompare2(TIM1,CMP2);
                TIM_SetCompare3(TIM1,CMP3);


            }


        }

}
void GPIO_config()
{
    GPIO_InitTypeDef GPIO_InitStructure={0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOE, &GPIO_InitStructure );
    GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);

}
void TIM_config()
{
    NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

    TIM_TimeBaseStructure.TIM_Period = (uint16_t)ARR_val-1;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
        TIM_OCInitStructure.TIM_Pulse = 0;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
        TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
        TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

    TIM_OC1Init(TIM1,&TIM_OCInitStructure);
    TIM_OC2Init(TIM1,&TIM_OCInitStructure);
    TIM_OC3Init(TIM1,&TIM_OCInitStructure);

    TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable;
    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable;
    TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
    TIM_BDTRInitStructure.TIM_DeadTime = 50;
    TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
    TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
    TIM_BDTRConfig( TIM1, &TIM_BDTRInitStructure );

    TIM_CtrlPWMOutputs(TIM1, ENABLE );
    TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Enable );
    TIM_OC2PreloadConfig( TIM1, TIM_OCPreload_Enable );
    TIM_OC3PreloadConfig( TIM1, TIM_OCPreload_Enable );
    TIM_ARRPreloadConfig( TIM1, ENABLE );
    TIM_Cmd( TIM1, ENABLE );

    TIM_TimeBaseStructure.TIM_Period = 4665;
    TIM_TimeBaseStructure.TIM_Prescaler =0;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );

    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    TIM_Cmd(TIM3, ENABLE);

}
void DAC_config()
{
    GPIO_InitTypeDef gpio_dac_structure;
    DAC_InitTypeDef dac_structure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);

    gpio_dac_structure.GPIO_Mode=GPIO_Mode_AIN;
    gpio_dac_structure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
    gpio_dac_structure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&gpio_dac_structure);

    dac_structure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
    dac_structure.DAC_OutputBuffer=DAC_OutputBuffer_Enable;
    dac_structure.DAC_Trigger=DAC_Trigger_None;
    dac_structure.DAC_WaveGeneration=DAC_WaveGeneration_None;
    DAC_Init(DAC_Channel_1, &dac_structure);
    DAC_Init(DAC_Channel_2, &dac_structure);

    DAC_Cmd(DAC_Channel_1,ENABLE);
    DAC_Cmd(DAC_Channel_2,ENABLE);
}
void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update))
    {
        sig_flag =1;
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
    }

}
void bound_check(float *var)
{
    if(*var ==360)
    {
        *var = 0;
    }
}
uint8_t sec_idn(float angle)
{
    uint8_t sec_sig;
    sec_sig = (angle/60 )+ 1;
    if(sec_sig == 7)
    {
        sec_sig =6;
    }
    return sec_sig;
}
void tim_cal(void)
{
//    uint8_t ac_f =0;
    T1 = sqrt(3)*T_svm*spc_mag*sinf((sector*PI/3)-spc_angle);
    T2 = sqrt(3)*T_svm*spc_mag*sinf(spc_angle-(sector-1)*PI/3);
    T0 = T_svm -T1 -T2;
}

